<?php
    namespace Spider\Site;

    use DOMWrap\Document;
    use GuzzleHttp\Cookie\SetCookie;
    use GuzzleHttp\Psr7\Response;
    use lactone\Core\Site\Site;

    class zhihu_com  extends Site{

        protected $host  = 'http://www.zhihu.com';

        public    $pdo;

        protected $connect;

        public function init(){

            parent::init();


            $pdo = array_merge(['options'=>[]],$this->pdo);
            $this->connect = new \PDO($pdo['dsn'],$pdo['username'],$pdo['password'],$pdo['options']);
        }

        /**
         * 登录
         * @return bool
         */
        public function Login(){

            $Cookies = [
                '__utma=51854390.804485098.1440397694.1442822120.1444628286.4; expires=Wed, 11 Oct 2017 05:38:05 GMT; path=/; domain=.zhihu.com',
                '__utmb=51854390.2.10.1444628286; expires=Mon, 12 Oct 2015 06:08:05 GMT; path=/; domain=.zhihu.com',
                '__utmc=51854390; path=/; domain=.zhihu.com',
                '__utmt=1; expires=Mon, 12 Oct 2015 05:48:05 GMT; path=/; domain=.zhihu.com',
                '__utmv=51854390.100-1|2=registration_date=20120722=1^3=entry_date=20120722=1; expires=Wed, 11 Oct 2017 05:38:05 GMT; path=/; domain=.zhihu.com',
                '__utmz=51854390.1440397694.1.1.utmcsr=zhihu.com|utmccn=(referral)|utmcmd=referral|utmcct=/topic; expires=Mon, 11 Apr 2016 17:38:05 GMT; path=/; domain=.zhihu.com',
                '_xsrf=08072fd6cc2bbe96f8b5e6e885e5a6e1; expires=Wed, 21 Oct 2015 07:55:18 GMT; path=/; domain=www.zhihu.com',
                '_za=b70ffd03-78d9-479c-85b1-b51b7c344a13; expires=Sun, 20 Aug 2017 07:25:48 GMT; path=/; domain=www.zhihu.com',
                'cap_id="NTE5YjNjZGE0ZjQ1NDFkZmFjZTE5OWJlYjc3YjE0YTk=|1442818920|75337b39ba85e0d67c6152406b53d6bb4483e1fa"; expires=Wed, 21 Oct 2015 07:01:49 GMT; path=/; domain=.zhihu.com',
                'q_c1=1e89404b1ce24e4e970addb94a18fa4b|1442818920000|1440142385000; expires=Thu, 20 Sep 2018 07:01:49 GMT; path=/; domain=.zhihu.com',
                'unlock_ticket="QUFDQWI0d1pBQUFYQUFBQVlRSlZUWDJ5XzFYMEFmazhQRy02SE0wUVdNbFYxeU8yeVNYdV9BPT0=|1442818933|8b8648dba82bae1619720f911215025abaf6089a"; expires=Mon, 21 Sep 2015 07:31:02 GMT; path=/; domain=.zhihu.com',
                'z_c0="QUFDQWI0d1pBQUFYQUFBQVlRSlZUWFU0SjFhMXMycFA4OWIwakJkdFdyeDhEVjhsNnJHZEVRPT0=|1442818933|237547cff881a587528012561fa077f764394ed4"; expires=Tue, 20 Sep 2016 07:02:01 GMT; path=/; domain=.zhihu.com; HttpOnly'
            ];
            $CookiesObject =  $this->getCookies();

            foreach($Cookies as $Cookie){
                $CookiesObject->setCookie(SetCookie::fromString($Cookie));
            }

            $CookiesObject->save($this->CookieDir.'/'.md5(get_called_class()).'.cookie');

            return true;


        }

        /**
         * 获取需要登录的其它数据
         * @return bool
         */
        private function getLoginData(){
            $respone = $this->Client->get("http://www.zhihu.com");

            $Status = $respone->getStatusCode();

            if($Status>=200 && $Status<300){

                $Html = $respone->getBody();
                $Document = new Document();

                $nodeList = $Document->html($Html->getContents())->find(".view-signin");

                if($nodeList->count()>0){
                    $node  =  $nodeList->first();
                    $hideInput = $node->find('input[name="_xsrf"]');

                    return ['_xsrf'=>$hideInput->getAttribute('value')];
                }

            }

            return false;
        }


        public function needLogin(){
            return true;
        }

        /**
         * 对数据进行处理
         * @param Response $response
         */
        public function process(Response $response){

            $path = $this->url->getPath();
            $html = $response->getBody();

            $task = [];

            \Lactone::info($this->logMessage($path,'task_Zhizhu'));

            //$this->CacheBody($response);

            switch($path){
                case '':
                case '/':
                    \Lactone::info($this->logMessage('首页','task_Zhizhu'));


                    $task = $this->loginIndexProcess($html);
                    break;
                case '/node/ProfileFollowersListV2':        //获取某用户当前关注的用户数量列表
                    \Lactone::info($this->logMessage('获取某用户当前关注的用户数量列表','task_Zhizhu'));

                    $task = $this->UserFollowersProcess($html);
                    break;
                default:
                    \Lactone::info($this->logMessage('其它','task_Zhizhu'));

                    //是否是在某用户关注的页面
                    if($this->isInUserContentFloowers($path)){
                        $task = $this->userContentFollowerProcess($html);
                        break;
                    }

                    //用户详情
                    if($this->isInUserContentDetails($path)){
                        $task = $this->userContentDetails($html);
                        break;
                    }


                    //用户中心
                    if($this->isInUserContent($path)){
                        $task = $this->userContentProcess($html);
                        break;
                    }

                    \Lactone::info($this->logMessage('当前页面啥都不是','task_Zhizhu'));

                    break;
            }

            \Lactone::info($this->logMessage('sendToServer','task_Zhizhu'));

            $this->sendToServer($task);

            return true;
        }

        /**
         * 缓存当前获取的html信息
         * @param Response $responses
         */
        protected function CacheBody(Response $response){
            $cacheConfig  = \Lactone::getConfig('cache');
            $cacheDir        = $cacheConfig['dir'];

            \Lactone::info($this->logMessage($cacheDir."".md5(json_encode($this->task)),'数据缓存地址'));

            file_put_contents($cacheDir."".md5(json_encode($this->task)),$response->getBody());
        }

        /**
         * 当前是否是在某用户的详情页面
         */
        public function isInUserContent($path){
            if(preg_match('|/people/(.+)$|',$path,$matches)){
                return true;
            }
            return false;
        }

        /**
         * 是否是在某用户关注的页面
         */
        public function isInUserContentFloowers($path){
            if(preg_match('|/people/(.+)/followers|',$path,$matches)){
                return true;
            }
            return false;
        }

        /**
         * 是否在用户详情页面
         */
        public function isInUserContentDetails($path){
            if(preg_match('|/people/(.+)/about$|',$path,$matches)){
                return true;
            }
            return false;
        }

        /**
         * 首页信息处理,获取当前有的数据的信息
         * @param $html
         */
        public function loginIndexProcess($html){

            $Document  = new \DOMWrap\Document();

            $nodeList  = $Document->html($html->__toString())->find("#js-home-feed-list .feed-item .avatar a");

            $task = [];
            $urls = [];

            foreach($nodeList as $node){
                $_path = $node->getAttribute('href');

                if(strpos($_path,'http') === false){
                    $url = $this->host.$_path;
                }else{
                    $url = $_path;
                }

                if(!in_array($url,$urls)){
                    $task[] = [
                        'url'       =>  $url,
                        'request'   =>  $this->createRequest('get'),
                        'p_id'      =>  $this->task['id'],
                        'level'     => 10
                    ];

                    $urls[] = $url;
                }

            }

            if(empty($nodeList)){
                \Lactone::info($this->logMessage("Cookie失效"));
            }

            \Lactone::debug($this->logMessage($task,'indexTasks'));

            return $task;
        }


        /**
         * 用户中心首页内容处理
         * 这里只负责保存用户的信息
         */
        public function userContentProcess($html){
            $task = [];
            //用户关注者
            $task[] = [
                'url'       => $this->task['url'].'/followers',
                'request'   => $this->createRequest('get'),
                'p_id'      =>  $this->task['id'],
                'level'     => 6
            ];
            //用户详细信息
            $task[] =[
                'url'       => $this->task['url'].'/about',
                'request'   => $this->createRequest('get'),
                'p_id'      =>  $this->task['id'],
                'level'     => 30
            ];
            return $task;
        }

        /**
         * 在用户关注页面进行数据的处理
         */
        public function userContentFollowerProcess($html){
            $task = [];
            $Document  = new \DOMWrap\Document();


            $HtmlDom = $Document->html($html->__toString());
            $nodeList = $HtmlDom->find(".zm-profile-header-op-btns button");
            if($nodeList->count() == 0)
                yield [];
            //hash_id的获取
            $node = $nodeList->first();
            $hash_id = $node->getAttribute('data-id');


            //_xsrf
            $nodeList = $HtmlDom->find("input[name='_xsrf']");
            if($nodeList->count() == 0){
                yield [];
            }

            $node = $nodeList->first();
            $_xsrf = $node->getAttribute('value');

            //关注总数
            $nodeList = $HtmlDom->find(".zm-profile-section-name");
            if($nodeList->count() == 0)
                yield [];
            $node = $nodeList->first();

            if(preg_match('|\s(\d)+\s|',$node->textContent,$matches)){
                $count = $matches[0];
                $step  = 20;

                $numbers = ceil($count/$step);

                \Lactone::warning("p_id:".$this->task['id'].",hash_id:".$hash_id.",number:".$numbers);

                for($i = 0;$i<=$numbers;$i++){
                    yield [
                        'url'       => $this->host.'/node/ProfileFollowersListV2',
                        'request'   => $this->createRequest('ajaxpost',false,[
                            'method'        =>'next',
                            'params'        =>json_encode([
                                'offset'    =>$step*$i,
                                'order_by'  => 'created',
                                'hash_id'   => $hash_id
                            ]),
                            '_xsrf'         =>$_xsrf
                        ]),
                        'p_id'      =>  $this->task['id'],
                        'level'     => 5
                    ];
                }


            }


        }

        /**
         * 查询用户列表数据
         * @param $html
         */
        protected function UserFollowersProcess($html){
            $results =  json_decode(urldecode($html));

            if($results && is_object($results)){
                if($results->r == 0){
                    foreach($results->msg as $Dom){
                        if(preg_match('|/people/(.+)/followers|',$Dom,$matches)){
                            yield [
                                'url'       => $this->host.'/people/'.$matches[1],
                                'request'   => $this->createRequest('get'),
                                'p_id'      =>  $this->task['id'],
                                'level'     => 20
                            ];
                        }
                    }
                }
            }

        }

        /**
         * 获取用户详情数据
         * zhihu_user
         *  tag_name 唯一标识名称
         *  nicename 名称
         *  sex 性别
         *  weibo 微博帐号
         *  headline 一句话介绍
         *  description 个人简介
         *  business 所在行业
         *  location 居住地(多)
         *  group  职业经历
         *  education 教育经历
         *  good_at 擅长
         *  questions 提问总数
         *  answer 回答总数
         *  posts 专栏文章
         *  collections 收藏
         *  logs  公共编辑
         *  followees 关注了总数
         *  followers 关注者总数
         *  columns_followed 关注了几个专栏
         *  topics_followed  关注了几个话题
         *  view_number 显示总数
         */
        public function userContentDetails($html){

            $Document  = new \DOMWrap\Document();
            $HtmlDom = $Document->html($html->__toString());
            $zhihu_user = [];
            $Find = function($string) use ($HtmlDom){
                return $HtmlDom->find($string);
            };

            if($temp = $this->htmlGetAttribute($Find(".zu-main-content .title-section a"),'href')){
                if(preg_match('|/people/(.+)$|',$temp,$matches)){
                    $zhihu_user['tag_name'] = $matches['1'];
                }

            }

            $zhihu_user['nicename'] = $this->htmlGetAttribute($Find(".zu-main-content .title-section a"),'textContent',false);
            $zhihu_user['headline'] = $this->htmlGetAttribute($Find(".zu-main-content .title-section .bio"),'textContent',false);
            $zhihu_user['weibo']    = $this->htmlGetAttribute($Find(".zu-main-content .weibo-wrap a"),'href');
            $zhihu_user['location']    = $this->htmlGetAttribute($Find(".zu-main-content .zm-profile-header-user-describe .location"),'title');
            $zhihu_user['business']    = $this->htmlGetAttribute($Find(".zu-main-content .zm-profile-header-user-describe .business"),'title');
            $zhihu_user['group']       = $this->htmlGetAttribute($Find(".zu-main-content .zm-profile-header-user-describe span.position "),'title');

            $zhihu_user['sex']         = $this->htmlGetAttribute($Find(".zu-main-content .zm-profile-header-user-describe .icon-profile-male "),'textContent',2);
            if($zhihu_user['sex'] !== 2) $zhihu_user['sex'] = 1;

            $zhihu_user['description'] = $this->htmlGetAttribute($Find(".zu-main-content .zm-profile-header-user-describe .zm-profile-header-description span.content"),'textContent');
            $zhihu_user['questions'] = $this->htmlGetAttribute($Find(".zu-main-content-inner .zm-profile-header .profile-navbar span.num "),'textContent');
            $zhihu_user['answer'] = $this->htmlGetAttribute($Find(".zu-main-content-inner .zm-profile-header .profile-navbar span.num "),'textContent',0,1);
            $zhihu_user['posts'] = $this->htmlGetAttribute($Find(".zu-main-content-inner .zm-profile-header .profile-navbar span.num "),'textContent',0,2);
            $zhihu_user['collections'] = $this->htmlGetAttribute($Find(".zu-main-content-inner .zm-profile-header .profile-navbar span.num "),'textContent',0,3);
            $zhihu_user['logs'] = $this->htmlGetAttribute($Find(".zu-main-content-inner .zm-profile-header .profile-navbar span.num "),'textContent',0,4);

            $zhihu_user['followees'] = $this->htmlGetAttribute($Find(".zu-main-sidebar .zm-profile-side-following strong"),'textContent',0);
            $zhihu_user['followers'] = $this->htmlGetAttribute($Find(".zu-main-sidebar .zm-profile-side-following strong"),'textContent',0,1);

            if($temp = $this->htmlGetAttribute($Find(".zu-main-sidebar .zg-link-litblue strong"),'textContent')){
                $zhihu_user['columns_followed'] = intval($temp);
            }else{
                $zhihu_user['columns_followed'] = 0;
            }

            if($temp = $this->htmlGetAttribute($Find(".zu-main-sidebar .zg-link-litblue strong"),'textContent',0,1)){
                $zhihu_user['topics_followed'] = intval($temp);
            }else{
                $zhihu_user['topics_followed'] = 0;
            }

            $zhihu_user['view_number'] =$this->htmlGetAttribute($Find(" .zu-main-sidebar .zm-profile-side-section .zm-side-section-inner strong"),'textContent',0,2);

            $columns = "`".join("`,`",array_keys($zhihu_user))."`";
            $value = "'".join("','",($zhihu_user))."'";

            $sql = "INSERT INTO zhihu_user(".$columns.") VALUES (".$value.")";

            $this->runSql($sql);

            return false;
        }

        /**
         * 执行sql语句
         * @param $sql
         */
        protected function runSql($sql){
            $pdo = array_merge(['options'=>[]],$this->pdo);
            try {
                $this->connect->query('SELECT 1');
            } catch (\PDOException $e) {
                $this->connect = new \PDO($pdo['dsn'],$pdo['username'],$pdo['password'],$pdo['options']);
            }

            $this->connect->exec($sql);
        }

        /**
         * 获取HTML节点的信息
         * @param $nodeList
         * @param $attr
         * @param int $defult
         * @return int
         */
        private function htmlGetAttribute($nodeList,$attr,$defult = false,$number = 0){
            if($nodeList->count() == 0)
               return $defult;

            if($number == 0){
                $node = $nodeList->first();
            }else{
                $node = $nodeList->get($number);
            }

            if( ( $attr == 'textContent' ) ){
                if(isset($node->textContent))
                    return $node->textContent;
                else
                    return $defult;
            }

            return  $node->getAttribute($attr);
        }
    }